#include "Gangster.h"
#include "Graphics.h"
#include "Controller.h"
#include "Field.h"
#include "Bullet.h"

#include <fstream>
#include <stdlib.h>

void Gangster::update( int updateNumber ) {
    if( !(getLifes() <= 0) ) {
        if( updateNumber == getLastUpdate() ) { return; }
        else { setLastUpdate( updateNumber ); }
        earnXP( 1 );
        if( timedLife() ) {
            loseTime();
            if( timeTillDeath() == 0 ) { return kill(); }
        }
        if( getXp() > getTargetXp() ) levelUp();
        if( getController() == 0 ) return;
        if( getController()->action() ) setUpdateStatus( true );
        /*if( getUpdateStatus() ){
            paint();
            setUpdateStatus( false );
        }*/
    }else return kill();
}

void Gangster::kill(){
    getField()->addDeath( getTeam() );
    getField()->destroy( getX(), getY() );
}

void Gangster::attack( Direction d ) {
    int x = getX(), y = getY();
    switch( d ){
        case     NORTH :         y -= 1; break;
        case NORTHEAST : x += 1; y -= 1; break;
        case      EAST : x += 1;         break;
        case SOUTHEAST : x += 1; y += 1; break;
        case     SOUTH :         y += 1; break;
        case SOUTHWEST : x -= 1; y += 1; break;
        case      WEST : x -= 1;         break;
        case NORTHWEST : x -= 1; y -= 1; break;
        default:                 return; break;
    }
    if( !getField()->spawnObject( x, y, new Bullet( x, y, getField(), true, d, 5 ) ) ) {
        getField()->objectAt( x, y )->damage( Bullet::DMGVALUE );
    }
}

void Gangster::save( ofstream* save, ofstream* config ) {
    (*save) << 'g';
    (*config) << 'G' << getLifes() << endl;
    switch( getTeam() ){
        case( TEAMENUM ): (*config) << char(TEAMENUMCHAR);  break;
        case( TEAMID ):   (*config) << char(TEAMIDCHAR);    break;
        case( TEAMDEMON ):(*config) << char(TEAMDEMONCHAR); break;
    }
    (*config) << getMoveSpeed() << endl
              << getController()->getType() << getShifts() << endl
              << getXp() << endl << getTargetXp() << endl << getLevel()
              << endl << timedLife() << endl << timeTillDeath() << endl
              << getSightRange() << endl;
}

void Gangster::damage( int value ) {
    int critChance;
    if( isPlayer() ) {
        critChance = BASEPLAYERCRITCHANCE - getLevel();
        if( critChance <= 0 ) critChance = 1;
        if( rand() % 100 < critChance ) {
            value = 2 * value;
        }
    } else {
        critChance = BASECRITCHANCE - getLevel();
        if( critChance <= 0 ) critChance = 1;
        if( rand() % 100 < critChance ) {
            value = 2 * value;
        }
    }
    earnLife( -value );
}

void Gangster::levelUp() {
    setTargetXp( getTargetXp() * 1.2 + 1 );
    earnLevel( 1 );
    setXp( 0 );
      // level rewards
    if( getLevel() % 10 == 0 ) earnLife();
    earnShift( (getLevel() % 5) );
}
